package com.hejjon.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hejjon.core.domain.entity.FeaturePublishRecord;
import com.hejjon.core.domain.entity.SysDatabase;
import com.hejjon.core.domain.vo.RecordRelTableInfoVO;
import com.hejjon.core.enumer.DeleteFlagEnum;
import com.hejjon.core.enumer.PublishStatusEnum;
import com.hejjon.core.exception.BusinessException;
import com.hejjon.core.utils.CollUtils;
import com.hejjon.core.utils.StrUtil;
import com.hejjon.domain.bo.RunSqlBO;
import com.hejjon.domain.dto.FeaturePublishInfoDTO;
import com.hejjon.domain.dto.RecordRelTableInfoDTO;
import com.hejjon.domain.vo.FeaturePublishDetailVO;
import com.hejjon.domain.vo.FeaturePublishRecordVO;
import com.hejjon.mapper.FeaturePublishRecordMapper;
import com.hejjon.service.IFeaturePublishRecordService;
import com.hejjon.service.IRecordRelTableInfoService;
import com.hejjon.service.ISysDatabaseService;
import com.hejjon.service.ISysMenuService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class FeaturePublishRecordServiceImpl extends ServiceImpl<FeaturePublishRecordMapper, FeaturePublishRecord> implements IFeaturePublishRecordService {


    @Resource
    private ISysDatabaseService databaseService;

    @Resource
    private FeaturePublishRecordMapper featurePublishRecordMapper;

    @Resource
    private IRecordRelTableInfoService recordRelTableInfoService;

    @Resource
    private ISysMenuService sysMenuService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveFeaturePublishInfo(FeaturePublishInfoDTO infoDTO) {

        SysDatabase database = databaseService.getById(infoDTO.getDatabaseId());
        if (database == null) {
            throw new BusinessException("数据库不存在! 请重新选择数据库");
        }

        FeaturePublishRecord entity = new FeaturePublishRecord();
        String recordId = StrUtil.getUUID();
        entity.setId(recordId);
        entity.setPublishName(infoDTO.getPublishName());
        entity.setCategoryId(infoDTO.getCategoryId());
        entity.setDatabaseId(infoDTO.getDatabaseId());
        entity.setPublishStatus(PublishStatusEnum.UNPUBLISH.getCode());
        entity.setDescription(infoDTO.getDescription());

        entity.setCreateBy("admin");
        entity.setDeleteFlag(DeleteFlagEnum.NO.getCode());
        entity.setCreateTime(LocalDateTime.now());

        List<String> featureIdList = infoDTO.getFeatureIdList();
        // 保存关联特征信息
        List<RecordRelTableInfoDTO> dtoList = new ArrayList<>();
        for (String featureId : featureIdList) {
            RecordRelTableInfoDTO dto = new RecordRelTableInfoDTO();
            dto.setRecordId(recordId);
            dto.setFeatureId(featureId);
            dtoList.add(dto);
        }

        try {
            featurePublishRecordMapper.insert(entity);
            recordRelTableInfoService.batchSave(dtoList);
        } catch (Exception e) {
            throw new BusinessException("保存发布记录失败, 异常信息: " + e.getMessage());
        }

        return true;
    }


    @Override
    public List<FeaturePublishRecordVO> listFeaturePublishInfo(FeaturePublishInfoDTO infoDTO) {

        List<FeaturePublishRecordVO> voList = featurePublishRecordMapper.selectFeaturePublishInfo(infoDTO);
        List<String> recordIds = voList.stream().map(FeaturePublishRecordVO::getRecordId).collect(Collectors.toList());
        List<RecordRelTableInfoVO> recordRelFeatureVOList = recordRelTableInfoService.listByRecordIds(recordIds);
        Map<String, RecordRelTableInfoVO> relFeatureVOMap = recordRelFeatureVOList.stream().collect(Collectors.toMap(RecordRelTableInfoVO::getRecordId, o -> o));
        voList.forEach(vo -> {
            String recordId = vo.getRecordId();
            RecordRelTableInfoVO featureVO = relFeatureVOMap.get(recordId);
            if (featureVO != null) {
                vo.setFeatureNames(featureVO.getFeatureNames());
                vo.setFeatureLabels(featureVO.getFeatureLabels());
            }
        });
        return voList;
    }

    @Override
    public boolean removeRecord(String recordId, String databaseId) {
        // 删除已发布的表
        List<RecordRelTableInfoVO> recordRelTableInfoVoList = recordRelTableInfoService.listByRecordId(recordId);
        List<String> tableNameList = recordRelTableInfoVoList.stream().map(RecordRelTableInfoVO::getTableName).collect(Collectors.toList());
        RunSqlBO runSqlBO = databaseService.loadRunSqlBO(databaseId);
        boolean succ = databaseService.executeDropTables(runSqlBO, tableNameList);
        boolean res = removeById(recordId);
        if (succ && res) {
            return recordRelTableInfoService.removeByRecordId(recordId);
        }
        return false;
    }


    @Override
    public void updatePublishStatus(String recordId, String status) {
        if (StringUtils.isEmpty(recordId) || StringUtils.isEmpty(status)) {
            return;
        }
        featurePublishRecordMapper.updatePublishStatus(recordId, status);
    }


    @Override
    public FeaturePublishDetailVO getFeaturePublishDetail(String recordId) {

        FeaturePublishDetailVO featurePublishDetailVO = featurePublishRecordMapper.selectFeaturePublishDetail(recordId);
        List<RecordRelTableInfoVO> recordRelTableInfoVoList = recordRelTableInfoService.listByRecordId(recordId);
        List<String> featureNameList = recordRelTableInfoVoList.stream().map(RecordRelTableInfoVO::getFeatureName).collect(Collectors.toList());
        List<String> featureLabelList = recordRelTableInfoVoList.stream().map(RecordRelTableInfoVO::getFeatureLabel).collect(Collectors.toList());
        List<String> tableNameList = recordRelTableInfoVoList.stream().map(RecordRelTableInfoVO::getTableName).collect(Collectors.toList());

        featurePublishDetailVO.setFeatureNameList(featureNameList);
        featurePublishDetailVO.setFeatureLabelList(featureLabelList);
        featurePublishDetailVO.setTableNameList(tableNameList);

        CollUtils.multiListJoinToStr(featurePublishDetailVO, FeaturePublishDetailVO.convertors());

        return featurePublishDetailVO;
    }

    @Override
    public boolean existByRecordId(String recordId) {
        return featurePublishRecordMapper.existById(recordId) > 0;
    }


    @Override
    public List<FeaturePublishRecordVO> listByMenuId(String menuId) {
        return Collections.emptyList();
    }

}
